package com.example.munidingwei

import android.app.*
import android.content.Context
import android.content.Intent
import android.location.Location
import android.location.LocationManager
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.app.ActivityCompat
import android.Manifest
import android.content.pm.PackageManager
import kotlinx.coroutines.*

/**
 * 前台服务，确保即使应用退到后台也能持续更新模拟位置
 */
class LocationForegroundService : Service() {
    
    companion object {
        private const val TAG = "LocationForegroundService"
        private const val NOTIFICATION_ID = 1001
        private const val CHANNEL_ID = "mock_location_channel"
        private const val CHANNEL_NAME = "模拟定位服务"
        private const val REPORT_INTERVAL = 30 // 上报间隔（秒）
        
        private var isRunning = false
        
        /**
         * 启动前台服务
         */
        fun start(context: Context, latitude: Double, longitude: Double, accuracy: Float) {
            val intent = Intent(context, LocationForegroundService::class.java).apply {
                putExtra("latitude", latitude)
                putExtra("longitude", longitude)
                putExtra("accuracy", accuracy)
            }
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
        }
        
        /**
         * 停止前台服务
         */
        fun stop(context: Context) {
            context.stopService(Intent(context, LocationForegroundService::class.java))
        }
        
        fun isServiceRunning(): Boolean = isRunning
    }
    
    private val serviceScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private var updateJob: Job? = null
    private lateinit var mockLocationProvider: MockLocationProvider
    
    // WakeLock 保持CPU运行
    private var wakeLock: PowerManager.WakeLock? = null
    
    // BackendClient 用于上报位置
    private var backendClient: BackendClient? = null
    
    private var currentLatitude: Double = 0.0
    private var currentLongitude: Double = 0.0
    private var currentAccuracy: Float = 5.0f
    
    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "前台服务创建")
        
        mockLocationProvider = MockLocationProvider(applicationContext)
        
        // 初始化BackendClient用于上报位置
        try {
            backendClient = MainApplication.getBackendClient(applicationContext)
            Log.d(TAG, "✅ BackendClient已初始化")
        } catch (e: Exception) {
            Log.e(TAG, "❌ BackendClient初始化失败: ${e.message}")
        }
        
        // 创建通知渠道（Android 8.0+）
        createNotificationChannel()
        
        // 获取 WakeLock，保持 CPU 运行
        try {
            val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
            wakeLock = powerManager.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK,
                "MockLocation::ForegroundServiceWakeLock"
            )
            Log.d(TAG, "WakeLock 已创建")
        } catch (e: Exception) {
            Log.e(TAG, "创建 WakeLock 失败: ${e.message}")
        }
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "========================================")
        Log.d(TAG, "前台服务启动命令 onStartCommand")
        Log.d(TAG, "========================================")
        
        intent?.let {
            currentLatitude = it.getDoubleExtra("latitude", 0.0)
            currentLongitude = it.getDoubleExtra("longitude", 0.0)
            currentAccuracy = it.getFloatExtra("accuracy", 5.0f)
            
            Log.d(TAG, "收到模拟位置: ($currentLatitude, $currentLongitude)")
        }
        
        // 保存服务状态和位置信息，用于自启动和重启
        saveServiceState()
        
        try {
            // 创建通知
            val notification = createNotification()
            Log.d(TAG, "通知已创建")
            
            // 启动前台服务，显示通知
            startForeground(NOTIFICATION_ID, notification)
            Log.d(TAG, "✅ startForeground 调用成功！通知应该已显示")
            
            // 获取 WakeLock，确保 CPU 不休眠
            wakeLock?.let {
                if (!it.isHeld) {
                    it.acquire(10 * 60 * 1000L /*10分钟超时*/)
                    Log.d(TAG, "✅ WakeLock 已获取！CPU 将保持运行")
                }
            }
            
            isRunning = true
            
            // 启动持续更新任务
            startContinuousUpdate()
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 启动前台服务失败: ${e.message}")
            e.printStackTrace()
        }
        
        // START_STICKY 确保服务被杀死后自动重启
        return START_STICKY
    }
    
    /**
     * 保存服务状态，用于自启动和崩溃恢复
     */
    private fun saveServiceState() {
        try {
            val prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
            prefs.edit().apply {
                putBoolean("service_was_running", true)
                putFloat("last_latitude", currentLatitude.toFloat())
                putFloat("last_longitude", currentLongitude.toFloat())
                putFloat("last_accuracy", currentAccuracy)
                putLong("last_service_time", System.currentTimeMillis())
                apply()
            }
            Log.d(TAG, "✅ 服务状态已保存")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 保存服务状态失败: ${e.message}")
        }
    }
    
    override fun onBind(intent: Intent?): IBinder? = null
    
    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "========================================")
        Log.d(TAG, "前台服务即将销毁")
        Log.d(TAG, "========================================")
        
        isRunning = false
        stopContinuousUpdate()
        serviceScope.cancel()
        
        // 释放 WakeLock
        wakeLock?.let {
            if (it.isHeld) {
                it.release()
                Log.d(TAG, "WakeLock 已释放")
            }
        }
        
        // 尝试重启服务（防止被系统杀死）
        try {
            val prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
            val autoRestart = prefs.getBoolean("auto_restart_enabled", true)
            
            if (autoRestart) {
                Log.d(TAG, "准备重启服务...")
                
                // 发送重启广播
                val restartIntent = Intent(ServiceRestartReceiver.ACTION_RESTART_SERVICE)
                restartIntent.setClass(applicationContext, ServiceRestartReceiver::class.java)
                sendBroadcast(restartIntent)
                
                Log.d(TAG, "✅ 已发送服务重启广播")
            }
        } catch (e: Exception) {
            Log.e(TAG, "❌ 重启服务失败: ${e.message}")
        }
    }
    
    override fun onTaskRemoved(rootIntent: Intent?) {
        super.onTaskRemoved(rootIntent)
        Log.d(TAG, "========================================")
        Log.d(TAG, "任务被移除 (用户可能从最近任务列表中划掉了应用)")
        Log.d(TAG, "========================================")
        
        // 即使任务被移除，服务也继续运行
        // 可以选择在这里重新创建任务或继续保持服务运行
        
        try {
            val prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
            val keepRunningAfterTaskRemoved = prefs.getBoolean("keep_running_after_task_removed", true)
            
            if (keepRunningAfterTaskRemoved) {
                Log.d(TAG, "✅ 服务将继续运行，即使应用任务被移除")
                
                // 重新启动服务以确保继续运行
                val restartIntent = Intent(applicationContext, LocationForegroundService::class.java)
                restartIntent.putExtra("latitude", currentLatitude)
                restartIntent.putExtra("longitude", currentLongitude)
                restartIntent.putExtra("accuracy", currentAccuracy)
                
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    startForegroundService(restartIntent)
                } else {
                    startService(restartIntent)
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "❌ 任务移除后重启失败: ${e.message}")
        }
    }
    
    /**
     * 创建通知渠道
     */
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                CHANNEL_NAME,
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "保持模拟定位服务运行"
                setShowBadge(false)
            }
            
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
            
            Log.d(TAG, "通知渠道已创建")
        }
    }
    
    /**
     * 创建通知
     */
    private fun createNotification(): Notification {
        // 点击通知打开应用
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            Intent(this, MainActivity::class.java),
            PendingIntent.FLAG_IMMUTABLE
        )
        
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("模拟定位运行中")
            .setContentText("位置: ${String.format("%.6f", currentLatitude)}, ${String.format("%.6f", currentLongitude)}")
            .setSmallIcon(android.R.drawable.ic_menu_mylocation)
            .setContentIntent(pendingIntent)
            .setOngoing(true) // 不可滑动删除
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setCategory(NotificationCompat.CATEGORY_SERVICE)
            .build()
    }
    
    /**
     * 更新通知内容
     */
    private fun updateNotification(updateCount: Int) {
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("模拟定位运行中")
            .setContentText("已更新 $updateCount 次 | ${String.format("%.6f", currentLatitude)}, ${String.format("%.6f", currentLongitude)}")
            .setSmallIcon(android.R.drawable.ic_menu_mylocation)
            .setOngoing(true)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()
        
        val notificationManager = getSystemService(NotificationManager::class.java)
        notificationManager.notify(NOTIFICATION_ID, notification)
    }
    
    /**
     * 启动持续更新任务
     */
    private fun startContinuousUpdate() {
        updateJob?.cancel()
        
        Log.d(TAG, "==== 启动前台服务持续更新 ====")
        Log.d(TAG, "模拟坐标: ($currentLatitude, $currentLongitude)")
        
        updateJob = serviceScope.launch {
            var updateCount = 0
            Log.d(TAG, "前台服务协程已启动")
            
            try {
                // 先添加 mock provider（在主线程）
                withContext(Dispatchers.Main) {
                    val result = mockLocationProvider.addMockLocationProvider()
                    Log.d(TAG, "Mock Provider 添加结果: $result")
                }
            } catch (e: Exception) {
                Log.e(TAG, "添加 Mock Provider 失败: ${e.message}")
                e.printStackTrace()
            }
            
            while (isActive) {
                try {
                    updateCount++
                    
                    // 更新模拟位置
                    mockLocationProvider.setMockLocation(
                        currentLatitude,
                        currentLongitude,
                        currentAccuracy
                    )
                    
                    // 每次都输出日志（方便看到后台是否还在运行）
                    Log.d(TAG, "🔥 [$updateCount] 位置更新成功 - 后台持续运行中！")
                    
                    // 每30秒上报一次位置到后台服务器
                    if (updateCount % REPORT_INTERVAL == 0) {
                        Log.d(TAG, "⏰ 到达上报时间点 (第 $updateCount 秒)")
                        reportLocationToBackend()
                    } else {
                        // 显示倒计时
                        val remaining = REPORT_INTERVAL - (updateCount % REPORT_INTERVAL)
                        if (remaining <= 5) {
                            Log.d(TAG, "⏳ 距离下次上报: $remaining 秒")
                        }
                    }
                    
                    // 每5次更新通知
                    if (updateCount % 5 == 0) {
                        Log.d(TAG, "📱 更新通知显示: 已更新 $updateCount 次")
                        withContext(Dispatchers.Main) {
                            updateNotification(updateCount)
                        }
                    }
                    
                    delay(1000) // 1秒
                    
                } catch (e: Exception) {
                    Log.e(TAG, "❌ 持续更新失败 (第 $updateCount 次): ${e.message}")
                    e.printStackTrace()
                }
            }
            
            Log.d(TAG, "前台服务协程已停止 (总更新 $updateCount 次)")
        }
        
        Log.d(TAG, "前台服务协程任务已提交")
    }
    
    /**
     * 停止持续更新任务
     */
    private fun stopContinuousUpdate() {
        Log.d(TAG, "停止前台服务持续更新")
        updateJob?.cancel()
        updateJob = null
        
        // 移除 mock provider
        mockLocationProvider.removeMockLocationProvider()
    }
    
    /**
     * 上报位置到后台服务器
     * 确保获取最新位置后再上报
     */
    private fun reportLocationToBackend() {
        try {
            Log.d(TAG, "========================================")
            Log.d(TAG, "🔍 开始上报位置到后台")
            Log.d(TAG, "========================================")
            
            if (backendClient == null) {
                Log.e(TAG, "❌ BackendClient未初始化，跳过上报")
                Log.e(TAG, "   请检查MainApplication是否正确初始化")
                return
            }
            
            Log.d(TAG, "✅ BackendClient已就绪")
            
            // 🔥 在上报前，尝试从LocationManager获取最新位置
            var latestLatitude = currentLatitude
            var latestLongitude = currentLongitude
            var latestAccuracy = currentAccuracy
            
            try {
                val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
                
                // 尝试从GPS provider获取最新位置
                if (ActivityCompat.checkSelfPermission(
                        this,
                        Manifest.permission.ACCESS_FINE_LOCATION
                    ) == PackageManager.PERMISSION_GRANTED
                ) {
                    val lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
                    if (lastKnownLocation != null) {
                        latestLatitude = lastKnownLocation.latitude
                        latestLongitude = lastKnownLocation.longitude
                        latestAccuracy = lastKnownLocation.accuracy
                        Log.d(TAG, "📍 从LocationManager获取到最新位置: ($latestLatitude, $latestLongitude)")
                    } else {
                        // 如果GPS没有，尝试NETWORK
                        val networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
                        if (networkLocation != null) {
                            latestLatitude = networkLocation.latitude
                            latestLongitude = networkLocation.longitude
                            latestAccuracy = networkLocation.accuracy
                            Log.d(TAG, "📍 从LocationManager(NETWORK)获取到最新位置: ($latestLatitude, $latestLongitude)")
                        } else {
                            Log.d(TAG, "📍 使用缓存位置: ($currentLatitude, $currentLongitude)")
                        }
                    }
                }
            } catch (e: Exception) {
                Log.w(TAG, "⚠️ 获取最新位置失败，使用缓存位置: ${e.message}")
            }
            
            // 更新缓存位置（如果获取到了新位置）
            if (latestLatitude != currentLatitude || latestLongitude != currentLongitude) {
                currentLatitude = latestLatitude
                currentLongitude = latestLongitude
                currentAccuracy = latestAccuracy
                Log.d(TAG, "✅ 已更新缓存位置为最新位置")
            }
            
            // 构造位置数据（使用最新获取的位置）
            val locationData = LocationData(
                latitude = latestLatitude,
                longitude = latestLongitude,
                accuracy = latestAccuracy,
                timestamp = System.currentTimeMillis(),
                address = "",
                isSimulated = true,
                locationName = ""
            )
            
            // 打印详细的位置信息
            Log.d(TAG, "📍 位置数据详情:")
            Log.d(TAG, "   纬度: $latestLatitude")
            Log.d(TAG, "   经度: $latestLongitude")
            Log.d(TAG, "   精度: $latestAccuracy 米")
            Log.d(TAG, "   时间戳: ${locationData.timestamp}")
            Log.d(TAG, "   是否模拟: ${locationData.isSimulated}")
            
            // 上报到后台
            Log.d(TAG, "📡 正在发送位置数据到后台服务器...")
            backendClient?.reportLocation(locationData)
            
            Log.d(TAG, "✅ 位置数据已发送")
            Log.d(TAG, "========================================")
            
        } catch (e: Exception) {
            Log.e(TAG, "========================================")
            Log.e(TAG, "❌ 上报位置失败!")
            Log.e(TAG, "   错误类型: ${e.javaClass.simpleName}")
            Log.e(TAG, "   错误信息: ${e.message}")
            Log.e(TAG, "   堆栈跟踪:", e)
            Log.e(TAG, "========================================")
        }
    }
}

